package com.menghao.rpc.consumer.handle;

import com.menghao.rpc.consumer.model.RpcRequest;
import com.menghao.rpc.util.RequestIdUtils;

import java.lang.reflect.Method;
import java.util.List;

/**
 * <p>Rpc框架消费方代理.<br>
 * <p>执行具体调用，子类实现Http、Tcp方式的Rpc请求<p/>
 * <p>需要保证线程安全（会被并发调用）</p>
 *
 * @author MarvelCode.
 */
public interface ReferenceAgent {

    /**
     * 通过rpc方式调用处理
     *
     * @param method 调用方法
     * @param args   调用参数
     * @return Object 调用结果
     */
    Object invoke(Method method, Object[] args);

    /**
     * 设置服务提供方主机信息
     *
     * @param hosts 主机列表
     */
    void setProviderHosts(List<String> hosts);

    /**
     * 返回服务契约
     *
     * @return 需要代理的接口
     */
    default String getContract() {
        return getSourceInterface().getName();
    }

    /**
     * 返回服务实现
     *
     * @return 需要代理的接口
     */
    String getImplCode();

    /**
     * 返回需要代理的接口
     *
     * @return 需要代理的接口
     */
    Class getSourceInterface();

    /**
     * 创建Rpc请求实体对象
     *
     * @param method 调用方法
     * @param args   方法入参
     * @return Rpc请求实体对象
     */
    default RpcRequest makeParam(Method method, Object[] args) {
        return RpcRequest.builder()
                .id(RequestIdUtils.nextId())
                .method(method.getName())
                .contract(getContract())
                .implCode(getImplCode())
                .args(args)
                .argsType(method.getParameterTypes())
                .build();
    }
}
